#ifndef _EK_KERNEL_H_
#define _EK_KERNEL_H_

/* This null indicate the functions and variables defined will be
 * export as system routines/variables */
#define KERNEL_EXPORT

#ifndef __ASSEMBLER__

#ifndef _EKOS_KERNEL_C_
#error "This file can be only included by kernel source"
#endif

#include <lib/string.h>
#include <lib/ioif.h>

#include <inc/types.h>
#include <inc/memlayout.h>
#include <inc/mmu.h>
#include <inc/error.h>
#include <inc/trap.h>
#include <inc/stdarg.h>
#include <inc/x86.h>
#include <inc/spinlock.h>
#include <inc/env.h>
#include <inc/sysconf.h>
#include <inc/signal.h>
#include <inc/stab.h>
#include <inc/pic.h>
#include <inc/iec.h>
#include <inc/ips.h>

/* 几个有用的符号 */
/* 这些符号在 kernel.ld 和 kernel.S 中定义 */
extern char				_start[], _text[], _text_end[], _bss[], _end[];
extern struct stab_t	__STAB_BEGIN__[];		// Beginning of stabs table
extern struct stab_t	__STAB_END__[];			// End of stabs table
extern char				__STABSTR_BEGIN__[];	// Beginning of string table
extern char				__STABSTR_END__[];		// End of string table

extern volatile ptab_entry_t vpt[];     // VA of "virtual page table"
extern volatile pdir_entry_t vpd[];     // VA of current page directory

#include <kernel/init.h>
#include <kernel/pcs.h>
#include <kernel/mem.h>
#include <kernel/intr.h>
#include <kernel/user.h>
#include <kernel/task.h>
#include <kernel/debug.h>
#include <kernel/perm.h>
#include <kernel/io.h>
#include <kernel/kpipe.h>
#include <kernel/ips.h>
#include <kernel/iec.h>
#include <kernel/sched.h>
#include <kernel/env.h>
#include <kernel/trapframe.h>

/* IDE DRIVER */

int ide_read(int drive, uint32_t lba, int nsectors, char *buf);
int ide_write(int drive, uint32_t lba, int nsectors, char *buf);

#define NOINTR_S { EFLAGS_T __flag=intr_disable_begin()
#define NOINTR_E intr_disable_end(__flag); }

#define INTR_S { EFLAGS_T __flag=intr_enable_begin()
#define INTR_E intr_enable_end(__flag); }

extern volatile struct dyninfo_t {
	 uint32_t upfhandler;
	 uint32_t veflags;
	 uint32_t si_cr3;

	 uint32_t kstack_alloc_tab[KSTACK_COUNT];
	 uint32_t kstack_alloc_free;
	 uint32_t kstack_alloc_inuse;
	 struct mutex_t kstack_alloc_lock;

	 /* Since user x stack is shared by all light processes of one
	  * parent, we need to lock it. And as we knows this structure
	  * will be shared with user stack, so we set a lock here */
	 struct mutex_t uxstack_lock;	 
} dyninfo;

#else

#define UPFHANDLER (DYNINFO)
#define VEFLAGS    (DYNINFO + 4)
#define SI_CR3     (DYNINFO + 8)

#endif

#endif /* _EK_KERNEL_H_ */
